#ifndef __RESUTL_STRUCT_H__
#define __RESUTL_STRUCT_H__
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>

using namespace std;
FILE *Json_file = fopen("json_file","w");
int m_flagMetric;

class Common
{
	public:
	enum {DISTANCE = 1, TIME = 2, ALL = 4};

	float m_distance;	// in meters
        char dist_text[10];

	float m_time;       // in sec
        char dur_text[10];
	
	double m_startLoc[2], m_endLoc[2];
	
	//int m_flagMetric = 4;

	void convert_dist()
	{	
		if (m_distance < 1000) {
			sprintf(dist_text,"%f metres", m_distance);
		}
		else {
			sprintf(dist_text,"%f km",m_distance/1000.0);
		}
	}
        
	void convert_time()
	{
		if (m_time < 60) {
			sprintf(dur_text,"%f seconds", m_time);
		}
		else {
			sprintf(dur_text,"%f min",m_time/60.0);
		}
	}

	void print()
	{
		if(m_flagMetric & ALL) {
			convert_dist();
			fprintf(Json_file,"\"distance\" : { \"text\" : \"%s\", \"value\" : %f },",dist_text,m_distance);
			convert_time();
			fprintf(Json_file,"\"duration\" : { \"text\" : \"%s\", \"value\" : %d },",dur_text,m_time);
		}

		else if (m_flagMetric & DISTANCE) {
			convert_dist();
			fprintf(Json_file,"\"distance\" : { \"text\" : \"%s\", \"value\" : %f },",dist_text,m_distance);
			fprintf(Json_file,"\"duration\" : { \"text\" : \"\", \"value\" : 0 },");
		}
		else if (m_flagMetric & TIME) {
			convert_time();
			fprintf(Json_file,"\"distance\" : { \"text\" : \"\", \"value\" : 0 },");
			fprintf(Json_file,"\"duration\" : { \"text\" : \"%s\", \"value\" : %d },",dur_text,m_time);
		}
		fprintf(Json_file,"\"start_location\" : [%f, %f], \"end_location\" : [%f, %f],",m_startLoc[0],m_startLoc[1],m_endLoc[0],m_endLoc[1]);
	}
};

class Step
{
	public:
	Common  m_comm;
	string  m_instruction;

	vector<pair<float,float> > m_polyline;

	void print()
	{
		int nrPoly = m_polyline.size();

		if (nrPoly > 0) 
		{
			fprintf(Json_file,"\"polyline\" : [ ");
		for (int i = 0; i < nrPoly; ++i) {
				fprintf(Json_file," [%f, %f]", m_polyline[i].first, m_polyline[i].second);

				if (i != nrPoly)
					fprintf(Json_file," , ");
			}

			fprintf(Json_file," ],");

			fprintf(Json_file,"%s ", m_instruction.c_str());
		}
	}
};

class Leg
{
	public:
	Common        m_comm;
	vector<Step>  m_steps;

	void print()
	{
		int nrSteps = m_steps.size();

		if (nrSteps > 0) 
		{
		
			fprintf(Json_file,"\"steps\" : [ ");

			for (int i = 0; i < nrSteps; ++i) {
				 fprintf(Json_file," { ");
				m_steps[i].print();
				fprintf(Json_file," } ");


				if (i != nrSteps - 1)
					fprintf(Json_file,", ");
			}
			fprintf(Json_file," ] ");

		}
	}
};

class Routes
{
	public:
	Common       m_comm;
	vector<Leg>  m_legs;
	
	void print()
	{
		int nrLegs = m_legs.size();
		printf("\nno of legs %d",nrLegs);
		if (nrLegs > 0) {
                        	
			fprintf(Json_file,"\"legs\" : [ ");
			for (int i = 0; i < nrLegs; ++i) 
			{
				printf("\nIn legs");
				fprintf(Json_file,"{");
				m_legs[i].m_comm.print();
				m_legs[i].print();
				fprintf(Json_file,"}");
				if (i != nrLegs - 1)
					fprintf(Json_file,", ");
			}
			fprintf(Json_file," ] ");

		}
	}
};

class Result
{
	public:
	// BB
	double m_nw[2];
	double m_se[2];

	// routes
	vector<Routes>  m_routes;

	void print()
	{
		fprintf(Json_file,"{\"boundingBox\" : { \"nw\" : [%f, %f], \"se\" : [%f, %f] }, ", m_nw[0], m_nw[1], m_se[0], m_se[1]);

		int nrRoutes = m_routes.size();
		printf("no.of routes :: %d", nrRoutes);
		if (nrRoutes > 0) {
			fprintf(Json_file,"\"routes\" : [ ");
			
			for (int i = 0; i < nrRoutes; ++i)
			{
				//printf("\nIn route printing");
				fprintf(Json_file," { ");
				m_routes[i].m_comm.print();
				m_routes[i].print();
				fprintf(Json_file," } ");

				if (i != nrRoutes - 1)
					fprintf(Json_file,", ");
			}

			fprintf(Json_file," ] ");
		}

		fprintf(Json_file," }");
	}
};


#endif
